package com.flexblog.components
{ import flash.events.MouseEvent;
	
	import flash.ui.Mouse;
	
	
	
	import mx.core.FlexGlobals;
	
	import mx.events.FlexEvent;
	
	import mx.events.MoveEvent;
	
	
	
	import spark.components.Button;
	
	import spark.effects.Move;
	
	import spark.effects.easing.Elastic;
	public class MagneticButton extends Button
		
	{
		
		// xAncor and yAncor determine the point to which 
		
		// the button returns when mouse cursor is too far away
		
		[Bindable] public var xAncor:Number = 0;
		
		[Bindable] public var yAncor:Number = 0;
		
		
		
		// Distance on x axis which determine maximum 
		
		// distance from xAncor in one direction
		
		[Bindable] public var xDist:Number = 100;
		
		
		
		// Distance on y axis which determine maximum 
		
		// distance from yAncor in one direction
		
		[Bindable] public var yDist:Number = 50;
		
		
		
		// Property that makes transitions between different positions
		
		private var _move:Move = new Move(this);
		
		
		
		
		public function MagneticButton()
			
		{
			
			super();
			
			
			
			/**
			 
			 * Tries to add event listener for mouse move event to stage. 
			 
			 * If stage is null than adds event listener for application 
			 
			 * complete and than adds event listener for mouse move
			 
			 */ 
			
			try
				
			{
				
				_move.easer = new Elastic();
				
				_move.duration = 1500;
				
				
				
				xAncor = this.x;
				
				yAncor = this.y;
				
				FlexGlobals.topLevelApplication.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouse_move);
				
			}
			
			catch(e:Error)
				
			{
				
				FlexGlobals.topLevelApplication.addEventListener(FlexEvent.APPLICATION_COMPLETE, app_complete);
				
			}
			
		}
		
		
		
		/**
		 
		 * Function that is called when Main application is complete. 
		 
		 * It sets easer property and duration property for _move, set ancor 
		 
		 * of the button to the buttens current x and y position and as 
		 
		 * mentioned above adds an event listener for mouse move
		 
		 */
		
		private function app_complete(e:FlexEvent):void
			
		{
			
			_move.easer = new Elastic();
			
			_move.duration = 1500;
			
			
			
			xAncor = this.x;
			
			yAncor = this.y;
			
			
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouse_move);
			
		}
		
		
		
		/**
		 
		 * Sets the ancor of the button and also move it to that position.
		 
		 */ 
		
		public function setAncor(_x:Number,_y:Number):void
			
		{
			
			xAncor = _x;
			
			yAncor = _y;
			
			_move.xTo = _x;
			
			_move.yTo = _y;
			
			_move.play();
			
		}
		
		
		
		/**
		 
		 *  Function that actually calculates and moves the button to the right position.
		 
		 */
		
		private function mouse_move(e:MouseEvent):void
			
		{
			
			// Some basic math logic to calculate if mouse cursor 
			
			// is close enough to move the button to that location
			
			if ( Math.abs((xAncor + this.width/2) - stage.mouseX) < 2*xDist && 
				
				Math.abs((yAncor + this.height/2) - stage.mouseY) < 2*yDist )
				
			{
				
				_move.xTo = stage.mouseX - this.width/2;
				
				_move.yTo = stage.mouseY - this.height/2;
				
			}
				
			else
				
			{
				
				_move.xTo = xAncor;
				
				_move.yTo = yAncor;
				
			}
			
			_move.play();
			
		}
		
	}
}